<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    var data = {
        name: "张三",
        age: 18,
        height: "177cm",
        weight: "70kg",
    };

    // 传统JS中, 给一个对象的每个属性配置取值拦截和赋值拦截  (vue)
    /* for(let key in data){
        let defaultValue = data[key];
        Object.defineProperty(data,key,{
            get:function(){ // 取值拦截
                console.log(`对${key}属性取值`);
                return defaultValue;
            },
            set:function(val){  // 赋值拦截
                console.log(`对${key}属性赋值`,val);
                defaultValue = val;
            }
        })
    }

    console.log(data.name);
    data.name = "李四"
    console.log(data.name); */


    // 代理:  根据原本的对象得到新对象 -> 所有对新对象的操作,可以同步到原对象
    // 简易代理
   /*  function MyProxy(data) {
        // {}
        // this -> {}
        for (let key in data) {
            Object.defineProperty(this, key, {
                get: function () { // 取值拦截
                    console.log(`对${key}属性取值`);
                    return data[key];
                },
                set: function (val) {  // 赋值拦截
                    console.log(`对${key}属性赋值`, val);
                    data[key] = val;
                }
            })
        }
        // return obj;
    }

    var proxy = new MyProxy(data);
    console.log(proxy);

    console.log(proxy.name); */



    /* function MyProxy(data, handlerOptions) {
        // {}
        // this -> {}
        for (let key in data) {
            Object.defineProperty(this, key, {
                get: function () { //对新对象 ->  取值拦截
                    console.log(`对${key}属性取值`);
                    // return data[key];
                    return handlerOptions.get(data,key);
                },
                set: function (val) { //对新对象 ->  赋值拦截
                    console.log(`对${key}属性赋值`, val);
                    // data[key] = val;
                    return handlerOptions.set(data,key,val);
                }
            })
        }
        // return obj;
    }

    var proxy = new MyProxy(data,{
        get:function(data,key){
            return data[key];
            // return "你在想屁吃";
            // return undefined;
        },
        set:function(data,key,val){
            // data[key] = val;
            return null;
        }
    });
    console.log(proxy);

    console.log(proxy.name);
    console.log(proxy.age);
    
    proxy.name = "李四";
    
    console.log(proxy.name); */



    // roxy 可以理解成，在目标对象之前架设一层“拦截”，外界对该对象的访问，都必须先通过这层拦截，因此提供了一种机制，可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理，用在这里表示由它来“代理”某些操作，可以译为“代理器”。

    

    var data = {
        name: "张三",
        age: 18,
        height: "177cm",
        weight: "70kg",
    };


    // 根据源对象生成新对象 => 操作源对象都要通过新对象执行
    // new Proxy(target,handler)
    // target => 源对象
    // handler  => 拦截处理


    // 1. 此代码=> handler中没有配置任何拦截效果，访问proxy就等同于访问target。
    /* var proxy = new Proxy(data,{});
    console.log("proxy",proxy);

    console.log(proxy.name);
    console.log(proxy.age);

    proxy.name="李四";
    proxy.age=28;
    console.log("源对象",data); */


    var proxy = new Proxy(data,{
        get:function(target,key){  // 对代理对象取值时触发 
            // target 源对象
            // key    取值的键名
            console.log("对代理对象取值",target === data);
            console.log("对代理对象取值",key);
            // return target[key];
            // return null;
            return "你在想什么?";
        },
        set:function(target,key,val){  // 对代理对象赋值时触发 
            // target[key] = val;
            // return undefined;   => 对象只读 (只能取值不能赋值)
        }
    });

    console.log("proxy",proxy);
    console.log("data",proxy);
    console.log(proxy === data);

    // console.log(proxy.name);
    // console.log(proxy.age);
    console.log(proxy.aaaa);

    // proxy.name="李四";
    // proxy.age=28;
    // console.log("源对象",data);





</script>

</html>